package com.irdstudio.efp.esb.api.service.yed.apply;

import com.alibaba.fastjson.JSON;
import com.irdstudio.basic.framework.core.base.FrameworkService;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.util.StringUtil;
import com.irdstudio.efp.basic.framework.mq.client.producer.MQProducerMessageClient;
import com.irdstudio.efp.basic.framework.mq.constant.TagEnums;
import com.irdstudio.efp.basic.framework.mq.constant.TopicEnums;
import com.irdstudio.efp.esb.api.rest.yed.req.YedApplyBackReqBean;
import com.irdstudio.efp.esb.api.service.common.repository.LmtRepository;
import com.irdstudio.efp.esb.api.service.common.repository.NlsRepository;
import com.irdstudio.efp.limit.service.vo.LmtPrdContVO;
import com.irdstudio.efp.nls.common.constant.PrdAdaptedSoltEnums;
import com.irdstudio.efp.nls.service.facade.NlsApplyInfoService;
import com.irdstudio.efp.nls.service.facade.UpdateLmtPrdContService;
import com.irdstudio.efp.nls.service.facade.psd.NlsApplyApprovalInfoService;
import com.irdstudio.efp.nls.service.vo.NlsApplyInfoVO;
import com.irdstudio.efp.nls.service.vo.psd.NlsApplyApprovalInfoVO;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.irdstudio.efp.nls.service.common.rules.apply.ApplyExistRule;
import com.irdstudio.efp.nls.service.common.rules.apply.ApplySuccessOrFailureRule;
import com.irdstudio.efp.nls.service.common.rules.apply.HasCreditInfoRule;
import com.irdstudio.efp.nls.service.common.rules.apply.ValidateLmtPrdContRule;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.Date;

import static com.irdstudio.basic.framework.core.constant.BaseConstant.ADMIN;
import static com.irdstudio.basic.framework.core.constant.BaseConstant.NLS_APPLY_STATE_03;
import static com.irdstudio.efp.nls.common.constant.yed.YedCommonConstant.FLOW_STATUS_3;

/**
 * 优e贷风控审批结果通知后处理
 *
 * @author liangcongming :2020/7/31 15:55
 * @version 0.1
 * @date 2020/7/31 15:55
 * @since 2020/7/31 15:55
 */
@Service("yedApplyBackService")
public class YedApplyBackService implements FrameworkService {

    private static Logger logger = LoggerFactory.getLogger(YedApplyBackService.class);

    @Autowired
    private NlsRepository nlsRepository;
    @Autowired
    private LmtRepository lmtRepository;
    @Autowired
    @Qualifier("producerService")
    private MQProducerMessageClient producerService;
    @Autowired
    @Qualifier("nlsApplyApprovalInfoService")
    private NlsApplyApprovalInfoService nlsApplyApprovalInfoService;
    @Autowired
    @Qualifier("updateLmtPrdContService")
    private UpdateLmtPrdContService updateLmtPrdContService;
    @Autowired
    @Qualifier("nlsApplyInfoService")
    private NlsApplyInfoService nlsApplyInfoService;

    public void processApply(YedApplyBackReqBean yedApplyBackReqBean) throws BizException {
        try {
            NlsApplyInfoVO selectNlsApplyInfo =  nlsRepository.getNlsApplyInfoBySeq(yedApplyBackReqBean.getUseCrdtAppSrlNo());

            NlsApplyInfoVO nlsApplyInfoVO = new NlsApplyInfoVO();
            nlsApplyInfoVO.checkFor(new ApplyExistRule(selectNlsApplyInfo));
            //nlsApplyInfoVO.checkFor(new ApplySuccessOrFailureRule(selectNlsApplyInfo));
            NlsCreditInfoVO nlsCreditInfoVO = nlsRepository.getNlsCreditInfoBySeq(selectNlsApplyInfo.getLmtApplySeq());
            nlsApplyInfoVO.checkFor(new HasCreditInfoRule(nlsCreditInfoVO));
            LmtPrdContVO lmtPrdCont = lmtRepository.getActiveLmtPrdCont(selectNlsApplyInfo.getLmtApplySeq());
            nlsApplyInfoVO.checkFor(new ValidateLmtPrdContRule(lmtPrdCont));

            updateNlsApplyInfo(selectNlsApplyInfo, yedApplyBackReqBean);
            insertApplyResult(selectNlsApplyInfo, yedApplyBackReqBean);
            if (isApproveAccess(yedApplyBackReqBean)) {
                insertLoanCtrContract(selectNlsApplyInfo, nlsCreditInfoVO, lmtPrdCont);
                sendMessageIfApproveAccess(selectNlsApplyInfo);
            } else {
                updateLmtPrdContService.recoverLmtPro(nlsCreditInfoVO.getLmtApplySeq(), nlsApplyInfoVO.getApplySeq());
            }

        } catch (BizException e) {
            logger.error(e.getMessage());
            throw e;
        } catch (UnsupportedEncodingException e) {
            logger.error("优e贷用信申请发送消息到mq出现异常", e.getMessage());
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "优e贷用信申请发送消息到mq出现异常");
        }
    }

    private void updateNlsApplyInfo(NlsApplyInfoVO nlsApplyInfoVO, YedApplyBackReqBean yedApplyBackReqBean) throws BizException {
        if (isApproveAccess(yedApplyBackReqBean)) {
            nlsApplyInfoVO = setFieldForApproveYes(nlsApplyInfoVO, yedApplyBackReqBean);
        } else {
            nlsApplyInfoVO = setFieldForApproveNo(nlsApplyInfoVO, yedApplyBackReqBean);
        }
        try {
            nlsApplyInfoService.updateByPk(nlsApplyInfoVO);
        } catch (Exception e) {
            logger.error("优e贷用信通知接口 用信申请流水号:【" + nlsApplyInfoVO.getApplySeq() + "】 更新风控审批结果时出错!" + e.getMessage());
            throw new BizException(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "更新风控审批结果时出错：" + e.getMessage());
        }
    }

    private boolean isApproveAccess(YedApplyBackReqBean yedApplyBackReqBean) {
        return "Y".equals(yedApplyBackReqBean.getAprvlRsltFlg()) ? true : false;
    }

    private boolean isApproveException(YedApplyBackReqBean yedApplyBackReqBean) {
        return "E".equals(yedApplyBackReqBean.getAprvlRsltFlg()) ? true : false;
    }

    private boolean isApproveFailure(YedApplyBackReqBean yedApplyBackReqBean) {
        return "N".equals(yedApplyBackReqBean.getAprvlRsltFlg()) ? true : false;
    }

    private NlsApplyInfoVO setFieldForApproveYes(NlsApplyInfoVO nlsApplyInfoVO, YedApplyBackReqBean yedApplyBackReqBean) {
        nlsApplyInfoVO.setSoltStage(PrdAdaptedSoltEnums.PsdSoltStageEnum.LETTER_BACK.getVALUE());
        nlsApplyInfoVO.setHsdRefuseCode(yedApplyBackReqBean.getRfsCd());
        nlsApplyInfoVO.setHsdRefuseReason(yedApplyBackReqBean.getRfsRsn());
        nlsApplyInfoVO.setApproveFlag(yedApplyBackReqBean.getAprvlRsltFlg());
        nlsApplyInfoVO.setFlowStatus(FLOW_STATUS_3);
        return nlsApplyInfoVO;
    }

    private void insertApplyResult(NlsApplyInfoVO selectNlsApplyInfo, YedApplyBackReqBean yedApplyBackReqBean) throws BizException {
        NlsApplyApprovalInfoVO nlsApplyApprovalInfoVO = new NlsApplyApprovalInfoVO();
        nlsApplyApprovalInfoVO.setAppFlowNo(selectNlsApplyInfo.getApplySeq());
        nlsApplyApprovalInfoVO.setApprovalResult(yedApplyBackReqBean.getAprvlRsltFlg());
        nlsApplyApprovalInfoVO.setRecImtRate(selectNlsApplyInfo.getLoanRate().longValue());
        nlsApplyApprovalInfoVO.setRefuseMsg(StringUtil.isNullorBank(yedApplyBackReqBean.getRfsRsn())?"":yedApplyBackReqBean.getRfsRsn());
        nlsApplyApprovalInfoVO.setRefuseCode(StringUtil.isNullorBank(yedApplyBackReqBean.getRfsCd())?"":yedApplyBackReqBean.getRfsCd());
        nlsApplyApprovalInfoVO.setCreateUser(ADMIN);
        nlsApplyApprovalInfoVO.setCreateTime(new Date());
        nlsApplyApprovalInfoVO.setLastUpdateUser(ADMIN);
        nlsApplyApprovalInfoVO.setLastUpdateTime(new Date());
        Integer result = nlsApplyApprovalInfoService.insert(nlsApplyApprovalInfoVO);
        if (result != 1) {
            logger.error("优e贷用信通知接口 用信申请流水号:【" + selectNlsApplyInfo.getApplySeq() + "】 插入风控审批结果时出错!");
            throw new BizException(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "更新风控审批结果时出错");
        }

    }

    private void sendMessageIfApproveAccess(NlsApplyInfoVO nlsApplyInfoVO) throws UnsupportedEncodingException {
        producerService.sendMsg(new Message(TopicEnums.YED_SIGN_CONTRACT_QUEUE_TASK_TOPIC.getTopicId(), TagEnums.YED_SIGN_CONTRACT_QUEUE_TASK.getTagId(), nlsApplyInfoVO.getApplySeq(),
                JSON.toJSONString(nlsApplyInfoVO).getBytes("UTF-8")));
    }

    private void insertLoanCtrContract(NlsApplyInfoVO nlsApplyInfoVO, NlsCreditInfoVO nlsCreditInfoVO, LmtPrdContVO lmtPrdContVO) throws BizException {
        nlsRepository.insertLoanCtrContract(nlsApplyInfoVO,nlsCreditInfoVO,lmtPrdContVO);
    }

    private NlsApplyInfoVO setFieldForApproveNo(NlsApplyInfoVO nlsApplyInfoVO, YedApplyBackReqBean yedApplyBackReqBean) {
        // 放款失败
        nlsApplyInfoVO.setDnSts(BaseConstant.DN_STS_0);
        // 用信审批为拒绝
        nlsApplyInfoVO.setNlsApplyState(NLS_APPLY_STATE_03);
        // 拒绝原因
        if (isApproveFailure(yedApplyBackReqBean)) {
            nlsApplyInfoVO.setRefuseCause("准入失败");
        } else if (isApproveException(yedApplyBackReqBean)) {
            nlsApplyInfoVO.setRefuseCause("风控系统异常");
        }
        return nlsApplyInfoVO;
    }

}
